package com.lj.back.manage.scaffold.module.job.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lj.back.manage.scaffold.common.DTO.PageQuery;
import com.lj.back.manage.scaffold.common.exception.MyException;
import com.lj.back.manage.scaffold.common.response.ResponseCodeConstant;
import com.lj.back.manage.scaffold.common.util.Assert;
import com.lj.back.manage.scaffold.module.job.DO.ScheduleJobDO;
import com.lj.back.manage.scaffold.module.job.DTO.ScheduleJobDTO;
import com.lj.back.manage.scaffold.module.job.dao.ScheduleJobDao;
import com.lj.back.manage.scaffold.module.job.enums.ScheduleJobOwnerEnum;
import com.lj.back.manage.scaffold.module.job.service.ScheduleJobService;
import com.lj.back.manage.scaffold.module.job.utils.ScheduleUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Scheduler;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 定时业务业务层实现类
 * @author lv
 * @version 1.0.0
 */
@Service
@Slf4j
@AllArgsConstructor
public class ScheduleJobServiceImpl implements ScheduleJobService {

    private final ScheduleJobDao scheduleJobDao;

    private final Scheduler scheduler;


    /**
     * 获取基本的查询条件
     * @return
     */
    private QueryWrapper<ScheduleJobDO> getBaseWrapper(){
        QueryWrapper<ScheduleJobDO> wrapper = new QueryWrapper();
        return wrapper;
    }

    /**
     * 分页查询定时任务列表
     * @param pageQuery 分页查询条件
     * @return 分页信息
     */
    @Override
    public Page<ScheduleJobDTO> listJobs(PageQuery pageQuery){
        Page<ScheduleJobDO> pageBean = new Page<>(pageQuery.getCurrent(),pageQuery.getSize());
        boolean flag = !StringUtils.isBlank(pageQuery.getKey());
        QueryWrapper<ScheduleJobDO> wrapper = getBaseWrapper().like(flag, "name", pageQuery.getKey())
                .or(flag)
                .like(flag, "bean", pageQuery.getKey());
        Page<ScheduleJobDO> page = scheduleJobDao.selectPage(pageBean, wrapper);
        List<ScheduleJobDTO> scheduleJobDTOS = page.getRecords().stream().map(scheduleJobDO -> BeanUtil.copyProperties(scheduleJobDO, ScheduleJobDTO.class))
                .collect(Collectors.toList());
        page.setRecords(null);
        Page<ScheduleJobDTO> dtoPage = new Page<>();
        BeanUtil.copyProperties(page,dtoPage);
        dtoPage.setRecords(scheduleJobDTOS);
        return dtoPage;
    }

    /**
     * 获取定时任务详情
     * @param id 任务ID
     * @return
     */
    @Override
    public ScheduleJobDTO getScheduleJobInfo(String id){
        QueryWrapper<ScheduleJobDO> wrapper = getBaseWrapper().eq("id", id);
        ScheduleJobDO scheduleJobDO = scheduleJobDao.selectOne(wrapper);
        if (null == scheduleJobDO){
            return null;
        }
        return BeanUtil.copyProperties(scheduleJobDO,ScheduleJobDTO.class);
    }

    /**
     * 修改定时任务详情
     * @param jobDTO
     * @return 是否成功
     */
    @Override
    public boolean updateScheduleJobCheckOwner(ScheduleJobDTO jobDTO){
        ScheduleJobDO scheduleJobDO = scheduleJobDao.selectById(jobDTO.getId());
        Assert.assertNotNull(scheduleJobDO,"需要修改的数据不存在,请联系管理员");
        if (ScheduleJobOwnerEnum.MANAGER.getCode() != scheduleJobDO.getOwner()){
            throw new MyException(ResponseCodeConstant.AUTHORIZATION_INSUFFICIENT, "该定时任务不能通过后台修改,请联系管理员修改该定时任务的拥有者");
        }
        updateScheduleJob(jobDTO);
        return true;
    }

    /**
     * 修改定时任务详情
     * @param jobDTO
     * @return 是否成功
     */
    @Override
    public boolean updateScheduleJob(ScheduleJobDTO jobDTO){
        ScheduleJobDO scheduleJobDO = scheduleJobDao.selectById(jobDTO.getId());
        Assert.assertNotNull(scheduleJobDO,"需要修改的数据不存在,请联系管理员");
        if (jobDTO.getStatus() != null){
            //操作定时任务
            ScheduleUtils.operateScheduleJob(scheduler,jobDTO.getId(),jobDTO.getStatus());
        }
        try{
            BeanUtil.copyProperties(jobDTO,scheduleJobDO);
            scheduleJobDao.updateById(scheduleJobDO);
        }catch (Exception e){
            log.error("修改定时任务信息异常", e);
            if (jobDTO.getStatus() != null){
                //还原定时任务
                ScheduleUtils.operateScheduleJob(scheduler,scheduleJobDO.getId(),scheduleJobDO.getStatus());
            }
        }
        return true;
    }

    /**
     * 启动定时任务
     * @param jobDTO
     * @return
     */
    @Override
    public boolean resumeScheduleJob(ScheduleJobDTO jobDTO){
        Long jobId = Long.valueOf(jobDTO.getId());
        //修改定时任务
        ScheduleUtils.resumeJob(scheduler,jobId);
        //修改数据库
        return updateScheduleJob(jobDTO);

    }

    /**
     * 暂停定时任务
     * @param jobDTO
     * @return
     */
    @Override
    public boolean pauseScheduleJob(ScheduleJobDTO jobDTO){
        Long jobId = Long.valueOf(jobDTO.getId());
        //修改定时任务
        ScheduleUtils.pauseJob(scheduler,jobId);
        //修改数据库
        return updateScheduleJob(jobDTO);
    }
}
